package com.hxexp.weixin.mvc.testpay.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hxexp.weixin.common.exception.APIException;
import com.hxexp.weixin.common.math.RandomUtil;
import com.hxexp.weixin.common.web.HttpUtil;
import com.qq.weixin.common.security.WeixinSignatureUtil;
import com.qq.weixin.constant.AppDevConstant;
import com.qq.weixin.mp.api.oauth2.Oauth2API;
import com.qq.weixin.mp.api.oauth2.model.WebAccessTokenBean;
import com.qq.weixin.mp.api.pay.PayAPI;
import com.qq.weixin.mp.api.pay.model.UnifiedOrderJaxb;
import com.qq.weixin.mp.api.pay.model.UnifiedOrderParamJaxb;

/**
 * 测试支付controller
 * @author li.jiang
 *
 */
@Controller
@RequestMapping(value="/testpay")
public final class TestPayController {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestPayController.class);
    @Autowired
    private Oauth2API oauth2API;
    @Autowired
    private PayAPI payAPI;

    @RequestMapping(value="/orderpay")
    public String orderPay(HttpServletRequest request, String code, Model model) {
        try {
            LOGGER.debug("################[/testpay/orderpay] code: " + code);
            WebAccessTokenBean tokenBean = oauth2API.getAccessToken(code, AppDevConstant.HxExpTest.APPID, AppDevConstant.HxExpTest.APPSECRET);
            LOGGER.debug("################[/testpay/orderpay] openid: " + tokenBean.getOpenid());

            HashMap<String, String> paramMap = new HashMap<String, String>(); // NOSONAR
            String orderId = String.format("%d%s", System.currentTimeMillis(), RandomUtil.getRandomString(4));
            paramMap.put("appid", AppDevConstant.HxExpTest.APPID);
            paramMap.put("mch_id", AppDevConstant.HxExpTest.MCHID);
            paramMap.put("nonce_str", RandomUtil.getRandomString(32)); // NOSONAR
            paramMap.put("body", "测试车票");
            paramMap.put("out_trade_no", orderId);
            paramMap.put("total_fee", "1");
            paramMap.put("spbill_create_ip", HttpUtil.getIpAddr(request)); // NOSONAR
            paramMap.put("notify_url", "http://weixin.huaxiaexpress.com.cn/weixin/paynotify/confirm.do"); // NOSONAR
            paramMap.put("trade_type", "JSAPI"); // NOSONAR
            paramMap.put("openid", tokenBean.getOpenid());
            String paySign = WeixinSignatureUtil.generatePaySign(AppDevConstant.HxExpTest.WXPAY_API_SECRETKEY, paramMap);

            UnifiedOrderParamJaxb paramJaxb = new UnifiedOrderParamJaxb();
            paramJaxb.setAppId(AppDevConstant.HxExpTest.APPID);
            paramJaxb.setMchId(AppDevConstant.HxExpTest.MCHID);
            paramJaxb.setNonceStr(paramMap.get("nonce_str"));
            paramJaxb.setBody("测试车票");
            paramJaxb.setOutTradeNo(orderId);
            paramJaxb.setTotalFee(1);
            paramJaxb.setSpbillCreateIp(paramMap.get("spbill_create_ip")); // NOSONAR
            paramJaxb.setNotifyUrl("http://weixin.huaxiaexpress.com.cn/weixin/paynotify/confirm.do"); // NOSONAR
            paramJaxb.setTradeType("JSAPI"); // NOSONAR
            paramJaxb.setOpenId(tokenBean.getOpenid());
            paramJaxb.setSign(paySign);
            UnifiedOrderJaxb uorderJaxb = payAPI.unifiedOrderAPI(paramJaxb);

            HashMap<String, String> payParamMap = new HashMap<String, String>(); // NOSONAR
            payParamMap.put("appId", AppDevConstant.HxExp.APPID);
            payParamMap.put("timeStamp", System.currentTimeMillis()/1000+"");
            payParamMap.put("nonceStr", RandomUtil.getRandomString(32)); // NOSONAR
            payParamMap.put("package", "prepay_id=" + uorderJaxb.getPrepayId());
            payParamMap.put("signType", "MD5");
            payParamMap.put("paySign", WeixinSignatureUtil.generatePaySign(AppDevConstant.HxExpTest.WXPAY_API_SECRETKEY, payParamMap));

            ObjectMapper mapper = new ObjectMapper();
            model.addAttribute("jsApiParam", mapper.writeValueAsString(payParamMap));

        } catch (Exception e) {
            LOGGER.error("发生异常", e);
        }
        return "paydemo";
    }

    @RequestMapping(value = "/wappay")
    public String wapPay(HttpServletRequest request, Model model) {
        try {
            HashMap<String, String> paramMap = new HashMap<String, String>(); // NOSONAR
            String orderId = String.format("%d%s", System.currentTimeMillis(), RandomUtil.getRandomString(4));
            paramMap.put("appid", AppDevConstant.HxExpTest.APPID);
            paramMap.put("mch_id", AppDevConstant.HxExpTest.MCHID);
            paramMap.put("nonce_str", RandomUtil.getRandomString(32)); // NOSONAR
            paramMap.put("body", "测试车票");
            paramMap.put("out_trade_no", orderId);
            paramMap.put("total_fee", "1");
            paramMap.put("spbill_create_ip", HttpUtil.getIpAddr(request)); // NOSONAR
            paramMap.put("notify_url", "http://101.204.230.158/wxt/paynotify/confirm.do"); // NOSONAR
            paramMap.put("trade_type", "MWEB"); // NOSONAR
            String paySign = WeixinSignatureUtil.generatePaySign(AppDevConstant.HxExpTest.WXPAY_API_SECRETKEY, paramMap);

            UnifiedOrderParamJaxb paramJaxb = new UnifiedOrderParamJaxb();
            paramJaxb.setAppId(AppDevConstant.HxExpTest.APPID);
            paramJaxb.setMchId(AppDevConstant.HxExpTest.MCHID);
            paramJaxb.setNonceStr(paramMap.get("nonce_str"));
            paramJaxb.setBody("测试车票");
            paramJaxb.setOutTradeNo(orderId);
            paramJaxb.setTotalFee(1);
            paramJaxb.setSpbillCreateIp(paramMap.get("spbill_create_ip")); // NOSONAR
            paramJaxb.setNotifyUrl("http://101.204.230.158/wxt/paynotify/confirm.do"); // NOSONAR
            paramJaxb.setTradeType("MWEB"); // NOSONAR
            paramJaxb.setSign(paySign);
            UnifiedOrderJaxb uorderJaxb = payAPI.unifiedOrderAPI(paramJaxb);
            LOGGER.info("预支付接口返回代码：{}", uorderJaxb.getReturnCode());
            LOGGER.info("预支付接口返回消息：{}", new String(uorderJaxb.getReturnMsg().getBytes(), "UTF-8")); // 测试未通过，提示商户没有H5支付权限

            HashMap<String, String> payParamMap = new HashMap<String, String>(); // NOSONAR
            payParamMap.put("appid", AppDevConstant.HxExpTest.APPID);
            payParamMap.put("timestamp", System.currentTimeMillis() / 1000 + "");
            payParamMap.put("noncestr", RandomUtil.getRandomString(32)); // NOSONAR
            payParamMap.put("package", "WAP");
            payParamMap.put("prepayid", uorderJaxb.getPrepayId());
            payParamMap.put("sign", WeixinSignatureUtil.generatePaySign(AppDevConstant.HxExpTest.WXPAY_API_SECRETKEY, payParamMap));
            String wapPayURL = String.format("weixin://wap/pay?appid=%s&noncestr=%s&package=%s&prepayid=%s&timestamp=%s&sign=%s",
                    payParamMap.get("appid"), payParamMap.get("noncestr"), payParamMap.get("package"), payParamMap.get("prepayid"),
                    payParamMap.get("timestamp"), payParamMap.get("sign"));
            wapPayURL = URLEncoder.encode(wapPayURL, "UTF-8"); // URL转码:转义特殊字符

            model.addAttribute("wapPayURL", wapPayURL);
        } catch (APIException e) {
            LOGGER.error("发生异常", e);
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("发生异常", e);
        }

        return "wappaydemo";
    }
}
